package com.dgut.Security;

import com.alibaba.fastjson.JSONObject;
import com.dgut.Service.utils.JwtTokenUtils;
import com.dgut.domain.IUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Value("${jwt.header}")
    private String token_header;

    @Autowired
    private JwtTokenUtils jwtUtils;

    @Override
    protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
//        //获取JWT
//        String authHeader = httpServletRequest.getHeader("Authorization");
//        logger.info("--------->"+authHeader);
//        if (authHeader != null) {
//            // 解析token.
//            Claims claims = Jwts.parser()
//                    .setSigningKey("MyJWTtest")
//                    .parseClaimsJws(authHeader.replace("Mrain", ""))
//                    .getBody();
//            //获取suject
////            String subject = claims.getSubject();
////            User user = (User) claims.get("user");
//            //获取过期时间
//            Date claimsExpiration = claims.getExpiration();
//            logger.info("过期时间"+claimsExpiration);
//            //判断是否过期
//            Date now = new Date();
//            if (now.getTime() > claimsExpiration.getTime()) {
//                throw new AuthenticationServiceException("凭证已过期，请重新登录！");
//            }
//            //获取保存在token中的登录认证成功的authentication，
//            // 利用UsernamePasswordAuthenticationToken生成新的authentication
//            // 放入到SecurityContextHolder，表示认证通过
//            Object tokenInfo = claims.get("authentication");
//            //通过com.alibaba.fastjson将其在转换。
//            Authentication toknAuthentication = JSONObject.parseObject(JSONObject.toJSONString(tokenInfo), Authentication.class);
//            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(toknAuthentication.getPrincipal(),null,toknAuthentication.getAuthorities());
//            SecurityContextHolder.getContext().setAuthentication(authentication);
//        }
//        filterChain.doFilter(httpServletRequest, httpServletResponse);

        String auth_token = httpServletRequest.getHeader(this.token_header);
        final String auth_token_start = "Bearer ";
        if (auth_token != null && auth_token.startsWith(auth_token_start)) {
            auth_token = auth_token.substring(auth_token_start.length());
            System.out.println(auth_token);
        } else {
            // 不按规范,不允许通过验证
            System.out.println("you must canonical your form");
            auth_token = null;
        }

        String username = jwtUtils.getUsernameFromToken(auth_token);

        logger.info(String.format("Checking authentication for userDetail %s.", username));

        if (jwtUtils.containToken(username, auth_token) && username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
            IUser userDetail = jwtUtils.getUserFromToken(auth_token);
            if (jwtUtils.validateToken(auth_token, userDetail)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetail, null, userDetail.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
                logger.info(String.format("Authenticated userDetail %s, setting security context", username));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(httpServletRequest, httpServletResponse);

    }
}
